﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TwinHead.Frameworks.Collections
{
    /// <summary>
    /// 컬렉션아이템이 루프 중간에 삭제되어도 무방할 수 있도록 해주는 Wrapper 클래스
    /// </summary>
    /// <example>
    ///	foreach (string s in new IterIsolate(hash.Keys))
    ///	{
    ///		if ((int) hash[s] == 0)
    ///			hash.Remove(s);
    ///	}
    /// </example>
    public class IterIsolate : IEnumerable
    {
        internal class IterIsolateEnumerator : IEnumerator
        {
            protected ArrayList items;
            protected int currentItem;

            internal IterIsolateEnumerator( IEnumerator enumerator )
            {
                // if this is the enumerator from another iterator, we
                // don't have to enumerate it; we'll just steal the arraylist
                // to use for ourselves. 
                IterIsolateEnumerator chainedEnumerator =
                    enumerator as IterIsolateEnumerator;

                if (chainedEnumerator != null)
                {
                    items = chainedEnumerator.items;
                }
                else
                {
                    items = new ArrayList();
                    while (enumerator.MoveNext() != false)
                    {
                        items.Add( enumerator.Current );
                    }
                    IDisposable disposable = enumerator as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }
                }
                currentItem = -1;
            }

            public void Reset()
            {
                currentItem = -1;
            }

            public bool MoveNext()
            {
                currentItem++;
                if (currentItem == items.Count)
                    return false;

                return true;
            }

            public object Current
            {
                get
                {
                    return items[currentItem];
                }
            }
        }

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="enumerable">A class that implements IEnumerable</param>
        public IterIsolate( IEnumerable enumerable )
        {
            this.enumerable = enumerable;
        }
        /// <summary>
        /// Enumerator를 리턴
        /// </summary>
        /// <returns></returns>
        public IEnumerator GetEnumerator()
        {
            return new IterIsolateEnumerator( enumerable.GetEnumerator() );
        }

        /// <summary>
        /// Enumerator
        /// </summary>
        protected IEnumerable enumerable;
    }
}
